package com.itshidu.game.controller

import com.baomidou.mybatisplus.core.conditions.Wrapper
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.itshidu.game.entity.Hero
import com.itshidu.game.entity.HeroItem
import com.itshidu.game.entity.User
import com.itshidu.game.mapper.FightLogMapper
import com.itshidu.game.mapper.HeroItemMapper
import com.itshidu.game.mapper.HeroMapper
import com.itshidu.game.mapper.UserMapper
import com.itshidu.game.service.FightService
import com.itshidu.game.utils.GameConfig
import org.apache.commons.lang3.StringUtils
import org.apache.commons.lang3.time.DateUtils
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model
import org.springframework.util.DigestUtils
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping

import javax.servlet.http.HttpSession;


@Controller
@Transactional
class GameController extends BaseController {

    @Autowired
    UserMapper userMapper;

    @Autowired
    HeroMapper heroMapper;
    @Autowired FightLogMapper fightLogMapper
    @Autowired HeroItemMapper heroItemMapper


    @RequestMapping("/login.html")
    login_html(Model model) {
        return "login";
    }
    @RequestMapping("/direction")
    direction(Model model) {
        return "direction";
    }

    @RequestMapping("/register.html")
    register_html(Model model) {
        return "register";
    }

    @RequestMapping("/register.do")
    register_do(Model model, String username, String password) {
        QueryWrapper wrapper = new QueryWrapper()
        wrapper.eq('username',username)
        int count = userMapper.selectCount(wrapper)
        if (count>0) {
            model.addAttribute("msg", "注册失败，用户名已存在")
            return "redirect:/register.html";
        }
        def user = new User()
        user.created = new Date()
        user.username = username
        user.password = md5(password)
        userMapper.insert(user)

        return "redirect:/login.html";
    }

    @RequestMapping("/login.do")
    login_do(Model model, String username, String password, HttpSession session) {
        def user = userMapper.findByUserName(username)
        if (user == null) {
            model.addAttribute("msg", "登录失败，用户名不存在")
            return "login";
        }
        if (!user.password.equals(md5(password))) {
            model.addAttribute("msg", "登录失败，密码不正确")
            return "login";
        }
        setCurrentUser(user)
        return "redirect:/my/hero";
    }

    // 游戏主页
    @RequestMapping(["/index","index.html","/"])
    index(Model model) {
        def user = getCurrentUser()
        if (user == null) {
            return "redirect:/login.html"
        }
        return "redirect:/my/hero";
    }

    // 角色列表
    @RequestMapping( ["/my/hero"])
    my_hero(Model model) {
        def user = getCurrentUser()
        QueryWrapper wrapper = new QueryWrapper()
        wrapper.eq('user_id', user.id)
        def list = heroMapper.selectList(wrapper)
        model.addAttribute('list', list)
        println(list.size())
        return "my_hero";
    }

    // 选用角色
    @RequestMapping("/my/hero/use/{hero_id}")
    my_hero_use(Model model, @PathVariable int hero_id) {
        def user = getCurrentUser()
        def hero = heroMapper.selectById(hero_id)
        if (hero == null) {
            return "redirect:/my/hero"
        }
        if (hero.userId != user.id) {
            return "redirect:/my/hero"
        }
        setCurrentHero(hero)
        return "redirect:/my/info";
    }

    // 创建角色
    @RequestMapping("/my/hero/create")
    my_hero_create(Model model, String name, String sex) {
        if (StringUtils.isBlank(name)) {
            return "redirect:/my/hero";
        }
        def user = getCurrentUser()
        def wrapper = new QueryWrapper()
        wrapper.eq('name', name)
        int count = heroMapper.selectCount(wrapper)
        if (count > 0) {
            return "redirect:/my/hero";
        }
        Hero hero = new Hero()
        hero.name = name
        hero.sex = sex
        hero.created = new Date()
        hero.userId = user.id
        heroMapper.insert(hero)

        /* 创建角色送经验丹 */
        def heroItem
        heroItem = new HeroItem()
        heroItem.heroId = hero.id
        heroItem.itemId = 3
        heroItemMapper.insert(heroItem)

        /* 创建角色送属性洗练丹 */
        heroItem = new HeroItem()
        heroItem.heroId = hero.id
        heroItem.itemId = 1
        heroItemMapper.insert(heroItem)



        return "redirect:/my/hero";
    }

    // 我的信息
    @RequestMapping("/my/info")
    my_info(Model model) {
        def hero = heroMapper.selectById(getCurrentHero().id)
        boolean isSameDay = DateUtils.isSameDay(hero.vigourTime, new Date())
        model.addAttribute("hero", hero)
        model.addAttribute("isSameDay", isSameDay)
        return "my_info";
    }

    // 我的背包
    @RequestMapping("/my/items")
    my_items(Model model) {
        return "my_items";
    }

    // 我的装备
    @RequestMapping("/my/equipment")
    my_equipment(Model model) {
        def hero = heroMapper.selectById(getCurrentHero().id)

        return "my_equipment";
    }

    // 我的技能
    @RequestMapping("/my/skill")
    my_skill(Model model) {
        return "my_skill";
    }

    //我的修炼
    @RequestMapping("/game/practice")
    my_practice(Model model) {
        def hero = heroMapper.selectById(getCurrentHero().id)
        model.addAttribute("hero", hero)
        return "my_practice";
    }

    //升级
    @RequestMapping("/game/upgrade")
    game_upgrade(Model model) {
        def hero = heroMapper.selectById(getCurrentHero().id)
        int _exp = hero.level * 1024
        if (hero.exp >= _exp) {
            hero.exp -= _exp
            hero.level += 1
            hero.ap += 1
            hero.hp += GameConfig.UPGRADE_HP;
            hero.mp += GameConfig.UPGRADE_MP;
            hero.atk += GameConfig.UPGRADE_ATK;
            hero.armor += GameConfig.UPGRADE_ARMOR;
            hero.hit += GameConfig.UPGRADE_HIT;
            hero.dodge += GameConfig.UPGRADE_DODGE;
            hero.critRate += GameConfig.UPGRADE_CRIT_RATE;
            hero.critVal += GameConfig.UPGRADE_CRIT_VAL;
            heroMapper.updateById(hero)
        }
        return "redirect:/game/practice";
    }

    @RequestMapping("/game/practice/start")
    upgrade_start(Model model) {
        def hero = heroMapper.selectById(getCurrentHero().id)
        int _exp = hero.level * 1024
        if (hero.state == 1 && hero.vigour >= 20) {
            hero.vigour -= 20
            hero.state = 2
            hero.practiceStartTime = new Date()
            heroMapper.updateById(hero)
        } else {
            return 'redirect:/game/practice'
        }
        return "my_practice_start";
    }

    @RequestMapping("/game/practice/stop")
    upgrade_stop(Model model) {
        def hero = heroMapper.selectById(getCurrentHero().id)
        int _exp = hero.level * 1024
        if (hero.state == 2) {
            hero.state = 1
            int second = (new Date().getTime() - hero.practiceStartTime.getTime()) / 1000;
            if (second > 14400) { //最多4小时
                second = 14400;
            }
            hero.exp += second;
            heroMapper.updateById(hero)
            model.addAttribute("hero", hero)
            model.addAttribute("practice_second", second)
        } else {
            return 'redirect:/game/practice'
        }
        return "my_practice_stop";
    }

    //补充体力
    @RequestMapping("/game/replenish")
    game_replenish(Model model) {
        def hero = heroMapper.selectById(getCurrentHero().id)
        boolean isSameDay = DateUtils.isSameDay(hero.vigourTime, new Date())
        if (!isSameDay) {
            hero.vigour = 100;
            hero.vigourTime = new Date()
            heroMapper.updateById(hero)
        }
        return "redirect:/game/practice";
    }

    //排行榜
    @RequestMapping("/game/ranking")
    game_ranking(Model model) {
        def wrapper = new QueryWrapper()
        wrapper.orderByDesc('level','exp')
        def page = new Page(1,15)
        def pageResult = heroMapper.selectPage(page,wrapper)
        def mine = heroMapper.selectById(getCurrentHero().id)
        model.addAttribute('list',pageResult.getRecords())
        model.addAttribute('mine',mine)
        return "/ranking";
    }

    //查看英雄信息
    @RequestMapping("/game/hero/{heroId}")
    game_hero_info(Model model,@PathVariable int heroId) {
        def hero = heroMapper.selectById(heroId)
        def mine = heroMapper.selectById(getCurrentHero().id)
        model.addAttribute('hero',hero)
        model.addAttribute('mine',mine)
        return "/hero-info";
    }

    @Autowired FightService fightService

    @RequestMapping("/game/fight/{heroId}")
    game_fight(Model model,@PathVariable int heroId) {
        if (getCurrentHero().id==heroId) {
            model.addAttribute('ret','无法挑战自己！')
            return "/hero-fight";
        }
        def hero = heroMapper.selectById(heroId)
        def mine = heroMapper.selectById(getCurrentHero().id)

        if (mine.vigour < 5) {
            model.addAttribute('ret','活力不足，无法挑战！')
            return "/hero-fight";
        }
        mine.vigour -= 5
        heroMapper.updateById(mine)
        def ret = fightService.fight(mine,hero,65536)
        model.addAttribute('ret',ret)
        return "/hero-fight";
    }

    //消息中心
    @RequestMapping("/game/my/message")
    game_message(Model model,String type) {
        def mine = heroMapper.selectById(getCurrentHero().id)
        if (type == '' || type == '1') { //防守日志
            def wrapper = new QueryWrapper()
            wrapper.eq('target_id',mine.id)
            wrapper.orderByDesc('created')
            def list = fightLogMapper.selectList(wrapper)
            list.forEach({ log ->
                log.hero = heroMapper.selectById(log.heroId)
                log.target = heroMapper.selectById(log.targetId)
                log.winner = heroMapper.selectById(log.winnerId)
            })
            model.addAttribute('title','防守日志')
            model.addAttribute('list',list)
        }
        if (type == '2') { //进攻日志
            def wrapper = new QueryWrapper()
            wrapper.eq('hero_id',mine.id)
            wrapper.orderByDesc('created')
            def list = fightLogMapper.selectList(wrapper)
            list.forEach({ log ->
                log.hero = heroMapper.selectById(log.heroId)
                log.target = heroMapper.selectById(log.targetId)
                log.winner = heroMapper.selectById(log.winnerId)
            })
            model.addAttribute('title','进攻日志')
            model.addAttribute('list',list)
            return "/my_message-2";
        }
        return "/my_message";
    }

    @RequestMapping("/game/fight/log/{log_id}")
    game_fight_log(Model model,@PathVariable int log_id) {
        def mine = heroMapper.selectById(getCurrentHero().id)
        def log = fightLogMapper.selectById(log_id)
        log.hero = heroMapper.selectById(log.heroId)
        log.target = heroMapper.selectById(log.targetId)
        log.winner = heroMapper.selectById(log.winnerId)
        model.addAttribute('fightLog',log)
        return "/fight-log";
    }

    @RequestMapping("/game/hero/attr")
    game_hero_attr(Model model) {
        def mine = heroMapper.selectById(getCurrentHero().id)
        model.addAttribute('hero',mine)
        return "hero-attr";
    }


    @RequestMapping("/game/hero/attr/set")
    game_hero_attr_set(Model model,int type) {
        def mine = heroMapper.selectById(getCurrentHero().id)
        if (mine.ap <= 0) {
            return 'redirect:/game/hero/attr'
        }
        if (type == 1) { //敏捷
            mine.apAgile += 1
            mine.agile += 1
        }
        if (type == 2) { //命中
            mine.apHit += 1
            mine.hit += 1
        }
        if (type == 3) { //闪避
            mine.apDodge += 1
            mine.dodge += 1
        }
        if (type == 4) { //暴击率
            mine.apCritRate += 1
            mine.critRate += 1
        }
        if (type == 5) { //暴击伤害
            mine.apCritVal += 1
            mine.critVal += 1
        }
        mine.ap -= 1
        heroMapper.updateById(mine)

        return 'redirect:/game/hero/attr'
    }


    public static String md5(String str) {
        String md5 = DigestUtils.md5DigestAsHex(str.getBytes())
        return md5;
    }

}
